package io.kiki.sba.registry.server.data_store.remoting.sessionserver.handler;


import io.kiki.sba.registry.api.Channel;
import io.kiki.sba.registry.common.model.Response;
import io.kiki.sba.registry.common.model.dataserver.GetMultiDataRequest;
import io.kiki.sba.registry.common.model.slot.MultiSlotAccessGenericResponse;
import io.kiki.sba.registry.common.model.slot.SlotAccess;
import io.kiki.sba.registry.common.model.slot.SlotAccessGenericResponse;
import io.kiki.sba.registry.common.model.store.DataCenterToSubDatumMap;
import io.kiki.sba.registry.common.model.store.SubDatum;
import io.kiki.sba.registry.util.StringFormatter;
import io.kiki.sba.registry.util.StringUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;


public class GetMultiDataHandler extends BaseGetDataHandler<GetMultiDataRequest> {

    @Override
    public void checkParam(GetMultiDataRequest request) {
        StringUtil.checkNotBlank(request.getDataInfoId(), "GetMultiDataRequest.dataInfoId");
        StringUtil.checkNotEmpty(request.getSlotsEpochs(), "GetMultiDataRequest.slotsEpochs");
        StringUtil.checkNotEmpty(request.getSlotLeaderEpochs(), "GetMultiDataRequest.slotLeaderEpochs");

        for (Entry<String, Long> entry : request.getSlotsEpochs().entrySet()) {
            String dataCenter = entry.getKey();
            StringUtil.nullValue(entry.getValue(), dataCenter + ".slotsEpoch");
            StringUtil.nullValue(request.getSlotLeaderEpochs().get(dataCenter), dataCenter + ".slotLeaderEpoch");
        }

        checkClientInterfaceId(request.getClientInterfaceId());
    }

    @Override
    public Class interest() {
        return GetMultiDataRequest.class;
    }


    @Override
    public MultiSlotAccessGenericResponse<DataCenterToSubDatumMap> doHandle(Channel channel, GetMultiDataRequest request) {
        processClientInterfaceId(channel, request.getClientInterfaceId());

        int dataCenterSize = request.getSlotLeaderEpochs().size();

        boolean success = true;
        StringBuilder sb = new StringBuilder();
        Map<String, SlotAccess> slotAccessMap = new HashMap<>(dataCenterSize);
        Map<String, SubDatum> dataCenterToSubDatumHashMap = new HashMap<>(dataCenterSize);
        for (Entry<String, Long> entry : request.getSlotsEpochs().entrySet()) {
            String dataCenter = entry.getKey();
            SlotAccessGenericResponse<SubDatum> slotAccessGenericResponse = processSingleDataCenter(dataCenter, request.getDataInfoId(), entry.getValue(), request.getSlotLeaderEpochs().get(dataCenter), request.getAcceptEncodes());

            if (!slotAccessGenericResponse.isSuccess()) {
                success = false;
                sb.append(StringFormatter.format("{}:{}.", dataCenter, slotAccessGenericResponse.getMessage()));
            }
            slotAccessMap.put(dataCenter, slotAccessGenericResponse.getSlotAccess());
            dataCenterToSubDatumHashMap.put(dataCenter, slotAccessGenericResponse.getData());
        }
        DataCenterToSubDatumMap dataCenterToSubDatumMap = new DataCenterToSubDatumMap(request.getDataInfoId(), dataCenterToSubDatumHashMap);

        return new MultiSlotAccessGenericResponse(success, sb.toString(), dataCenterToSubDatumMap, slotAccessMap);
    }

    @Override
    public Response buildFailedResponse(String msg) {
        return MultiSlotAccessGenericResponse.failedResponse(msg);
    }
}
